/**
 * 异步与后台交互
 */
import axios from './axios'
import _pick from 'lodash/pick'
import _assign from 'lodash/assign'
import _isEmpty from 'lodash/isEmpty'

import { assert } from 'Utils/tools'
import { API_DEFAULT_CONFIG } from 'Config'
import API_CONFIG from 'Service/api'


class MakeApi {
    constructor(options) {
        this.api = {}
        this.apiBuilder(options)
    }


    // API 默认配置
    // export const API_DEFAULT_CONFIG = {
    //     mockBaseURL: '', // 模拟的基础地址
    //     mock: true, // 是否开发模拟请求
    //     debug: false, //
    //     sep: '/' //     
    // }
    apiBuilder({
    	sep = '|',
    	mock = false, 
    	debug = false,
    	mockBaseURL = ''
    	config = {},
    }) {
    	Object.keys(config).map(namespace => {
    		this._apiSingleBuilder({
                sep, 
                mock, 
                debug, 
                mockBaseURL, 
                namespace, 
                config: config[namespace]
            })
    	})
    }
    // export default [{
    //     name: 'userinfo',
    //     method: 'GET',
    //     desc: '测试服务处',
    //     path: '/tomato/common/showAllGroup', // 线上接口地址
    //     mockPath: '/api/userinfo', // moke接口地址
    //     params: {
    //         a:1,
    //         b:2
    //     }
    // }]
    _apiSingleBuilder({
    	sep = '|',
    	mock = false, 
    	debug = false,
    	mockBaseURL = '',
    	namespace, 
    	config = [],
    }) {
        config.forEach( api => {
            const {name, desc, params, method, mockEnable, path, mockPath } = api
            const isMock = process.env.NODE_ENV === 'production' ? false : mock || mockEnable; // 生产环境不用moke数据
            const url = isMock ? mockPath : path
            const baseURL = isMock && mockBaseURL

            debug && assert(name, `${url} :接口name属性不能为空`)
            debug && assert(url.indexOf('/') === 0, `${url} :接口路径path，首字符应为/`)
            // 请求参数自动截取。
            // 请求参数不穿则发送默认配置参数。
            Object.defineProperty(this.api, `${namespace}${sep}${name}`, {
                value(outerParams, outerOptions) {
                    // 合并外部传入数据 在取原本的字段数据
                    const _data = _isEmpty(outerParams) ? params : _pick(_assign({}, params, outerParams), Object.keys(params))
                    const _options = isMock ? {url, desc, baseURL, method} : {url, desc, method}
                    return axios(_normoalize(_assign(_options, outerOptions), _data))
                }
            })      
        })
    }       
}

function _normoalize(options, data) {
    // 这里可以做大小写转换，也可以做其他类型 RESTFUl 的兼容
    if (options.method === 'POST') {
        options.data = data
    } else if (options.method === 'GET') {
        options.params = data
    }
    return options
} 
// 注入模型和全局配置，并暴露出去
export default new MakeApi({
	config: API_CONFIG,
	...API_DEFAULT_CONFIG
})['api']

